package cn.ztuo.bitrade.controller.product;

import cn.ztuo.bitrade.constant.TransactionTypeEnum;
import cn.ztuo.bitrade.controller.common.BaseAdminController;
import cn.ztuo.bitrade.dao.ContractOrderMapper;
import cn.ztuo.bitrade.dao.MemberDao;
import cn.ztuo.bitrade.entity.*;
import cn.ztuo.bitrade.service.BourseProductManagerService;
import cn.ztuo.bitrade.service.ContractOrderDetailService;
import cn.ztuo.bitrade.service.ContractOrderService;
import cn.ztuo.bitrade.service.LocaleMessageSourceService;
import cn.ztuo.bitrade.util.DateUtil;
import cn.ztuo.bitrade.util.MessageResult;
import cn.ztuo.bitrade.vo.product.ProductManagerAddReqVo;
import cn.ztuo.bitrade.vo.product.ProductManagerFindReqVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.util.Pair;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;


@RestController
@RequestMapping("product")
@Api(value = "产品相关的api",tags = "产品相关的api")
public class BourseProdecuManagerController extends BaseAdminController {
    @Autowired
    private BourseProductManagerService service;
    @Autowired
    private ContractOrderService contractOrderService;
    @Autowired
    private ContractOrderMapper contractOrderMapper;

    @Autowired
    private LocaleMessageSourceService messageSource;

    @Autowired
    private ContractOrderDetailService contractOrderDetailService;

    @Autowired
    private MongoTemplate mongoTemplate ;

    @Autowired
    private MemberDao memberDao ;

    @ApiOperation(value = "新增/修改产品", notes = "新增/修改产品 新增不传id,修改必须传id")
    @RequestMapping(value = "/saveAndUpdate", method = RequestMethod.POST)
    public MessageResult saveAndUpdate(@Validated ProductManagerAddReqVo reqVo) {
        ProductManagerFindReqVo vo = new ProductManagerFindReqVo();
        List<BourseProductManager> list = service.findAll(vo);
        List<BourseProductManager> list1 = list.stream().filter(a->((reqVo.getId()!=null&&a.getId().longValue()!=reqVo.getId().longValue())||reqVo.getId()==null)&&a.getProductCode().equals(reqVo.getProductCode())).collect(Collectors.toList());
        List<BourseProductManager> list2 = list.stream().filter(a->((reqVo.getId()!=null&&a.getId().longValue()!=reqVo.getId().longValue())||reqVo.getId()==null)&&a.getProductName().equals(reqVo.getProductName())).collect(Collectors.toList());

        if(list1!=null&&list1.size()>0){
            return MessageResult.error("产品编码已存在,请核实后操作!");
        }
        if(list2!=null&&list2.size()>0){
            return MessageResult.error("产品名称已存在,请核实后操作!");
        }
        BourseProductManager productManager = service.saveAndFlush(reqVo);
        return MessageResult.getSuccessInstance("", productManager);
    }

    @ApiOperation(value = "列表查询", notes = "列表查询分页")
    @RequestMapping(value = "/findAll", method = RequestMethod.POST)
    public MessageResult findAll(@Validated ProductManagerFindReqVo reqVo) {
        List<BourseProductManager> list = service.findAll(reqVo);
        return MessageResult.getSuccessInstance("", list);
    }
    @ApiOperation(value = "列表查询分页", notes = "列表查询分页")
    @RequestMapping(value = "/findAllByPage", method = RequestMethod.POST)
    public MessageResult findAllByPage(@Validated ProductManagerFindReqVo reqVo) {
        Page<BourseProductManager> page = service.findAllByPage(reqVo);
        return MessageResult.getSuccessInstance("", page);
    }

    @ApiOperation(value = "获取详情", notes = "获取详情")
    @RequestMapping(value = "/getById", method = RequestMethod.POST)
    public MessageResult getById(Long id) {
        BourseProductManager BourseProductManager = service.get(id);
        return MessageResult.getSuccessInstance("", BourseProductManager);
    }

    @ApiOperation(value = "操作", notes = "操作")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataType = "Long",required = true),
            @ApiImplicitParam(name = "status", value = "状态 1:正常 0:暂停", dataType = "int",required = true)}
    )
    @RequestMapping(value = "/stop", method = RequestMethod.POST)
    public MessageResult stop(Long id, int status) {
        BourseProductManager productManager = service.get(id);
        productManager.setStatus(status);
        service.saveAndFlush(productManager);
        return MessageResult.getSuccessInstance("", productManager);
    }


    //----------------------------------------------排行查询---------------------------------------------------

    /**
     * 币币换手率排行
     * @param
     * @return
     */
    @RequestMapping(value = "/rank", method = RequestMethod.POST)
    public MessageResult exchangeHandRate(String query) {
        JSONObject map = JSON.parseObject(query);
        if(map==null||!map.containsKey("type")||map.getInteger("type")==null){
            return MessageResult.error("请选择查询类型");
        }
        if(StringUtils.isBlank(map.getString("id"))){
            map.put("id",null);
        }
        if(StringUtils.isBlank(map.getString("name"))){
            map.put("name",null);
        }
        if(StringUtils.isBlank(map.getString("start"))){
            map.put("start",null);
        }
        if(StringUtils.isBlank(map.getString("end"))){
            map.put("end",null);
        }
        if(StringUtils.isBlank(map.getString("symbol"))){
            map.put("symbol",null);
        }
        Integer type = map.getInteger("type");
        List<Map<String,Object>> list = new ArrayList<>();
        switch(type){
            case 1 :
                //语句
                list = service.exchangeHandRate(map);
                break; //可选
            case 2 :
                //语句
                list = service.contractHandRate(map);
                break; //可选
            case 3 :
                //语句
                list = service.exchangeAmount(map);
                break; //可选
            case 4 :
                //语句
                list = service.contractAmount(map);
                break; //可选
            case 7 :
                //语句
                list = service.amountRank(map);
                break; //可选
            case 5 :
                //语句
                list = service.chargeRank(map);
                break; //可选
            case 6 :
                //语句
                list = service.extractRank(map);
                break; //可选
            //你可以有任意数量的case语句
            default : //可选
                //语句
                break;
        }
        return MessageResult.getSuccessInstance("", list);
    }


    @RequestMapping("updateContractDetailTypeAndUnit")
    public MessageResult updateContractDetailTypeAndUnit(){
        List<ContractOrder> orders = contractOrderService.findByStatus(ContractOrderStatus.COMPLETED);
        BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, "order_detail_aggregation");
        List<Pair<Query, Update>> list = new ArrayList<>();

        for (ContractOrder order : orders) {
            Query query = new Query();
            query.addCriteria(Criteria.where("orderId").is(order.getOrderId()).and("_class").is("cn.ztuo.bitrade.entity.ContractOrderDetailAggregation"));
            Update update = new Update();
            update.set("type", "CONTRACT");
            update.set("unit", order.getCoinSymbol());

            Pair<Query, Update> pair = Pair.of(query, update);
            list.add(pair);
        }
        operations.updateMulti(list);
        operations.execute();
        return MessageResult.success("");
    }

    @RequestMapping("statistics")
    public MessageResult statistics() throws ParseException {
        List<Date> list = getDateList();
        String dateStr = "";
        for(Date date :list){
            dateStr = DateUtil.YYYY_MM_DD.format(date) ;
            statisticsFee(dateStr,date);
        }
        return MessageResult.success("");
    }

    private void statisticsFee(String dateStr,Date date) throws ParseException {
//        /**
//         * 合约成交(按照交易对统计)
//         */
//        List<Object[]> list1 = contractOrderMapper.getContractTurnoverSymbol();
//        ExchangeTurnoverStatistics exchangeTurnoverStatistics = new ExchangeTurnoverStatistics() ;
//        for(Object[] objects:list1){
//            exchangeTurnoverStatistics.setDate(date);
//            exchangeTurnoverStatistics.setAmount((BigDecimal)objects[5]);
//            exchangeTurnoverStatistics.setBaseSymbol((String)objects[0]);
//            exchangeTurnoverStatistics.setCoinSymbol((String)objects[1]);
//            exchangeTurnoverStatistics.setMoney((BigDecimal)objects[4]);
//            exchangeTurnoverStatistics.setNowp((BigDecimal)objects[5]);
//            exchangeTurnoverStatistics.setYear(DateUtil.getDatePart(DateUtil.strToDate((String)objects[2],DateUtil.YYYY_MM_DD), Calendar.YEAR));
//            //Calendar month 默认从0开始，方便起见 保存月份从1开始
//            exchangeTurnoverStatistics.setMonth(DateUtil.getDatePart(DateUtil.strToDate((String)objects[2],DateUtil.YYYY_MM_DD),Calendar.MONTH)+1);
//            exchangeTurnoverStatistics.setDay(DateUtil.getDatePart(DateUtil.strToDate((String)objects[2],DateUtil.YYYY_MM_DD),Calendar.DAY_OF_MONTH));
//            mongoTemplate.insert(exchangeTurnoverStatistics,"contract_turnover_statistics");
//        }
//
//        /**
//         * 合约成交额
//         */

        /**
         * 合约成交(按照交易对统计)
         */
        List<Object[]> list = contractOrderMapper.getContractTurnoverSymbol(dateStr);
        ExchangeTurnoverStatistics exchangeTurnoverStatistics = new ExchangeTurnoverStatistics() ;
        for(Object[] objects:list){
            exchangeTurnoverStatistics.setDate(DateUtil.YYYY_MM_DD.parse(dateStr));
            exchangeTurnoverStatistics.setAmount((BigDecimal)objects[5]);
            exchangeTurnoverStatistics.setBaseSymbol((String)objects[0]);
            exchangeTurnoverStatistics.setCoinSymbol((String)objects[1]);
            exchangeTurnoverStatistics.setMoney((BigDecimal)objects[4]);
            exchangeTurnoverStatistics.setNowp((BigDecimal)objects[5]);
            exchangeTurnoverStatistics.setYear(DateUtil.getDatePart(date,Calendar.YEAR));
            //Calendar month 默认从0开始，方便起见 保存月份从1开始
            exchangeTurnoverStatistics.setMonth(DateUtil.getDatePart(date,Calendar.MONTH)+1);
            exchangeTurnoverStatistics.setDay(DateUtil.getDatePart(date,Calendar.DAY_OF_MONTH));
            mongoTemplate.insert(exchangeTurnoverStatistics,"contract_turnover_statistics");
        }



        TurnoverStatistics turnoverStatistics = new TurnoverStatistics();
        turnoverStatistics.setDate(DateUtil.YYYY_MM_DD.parse(dateStr));
        turnoverStatistics.setYear(DateUtil.getDatePart(date,Calendar.YEAR));
        //Calendar month 默认从0开始，方便起见 保存月份从1开始
        turnoverStatistics.setMonth(DateUtil.getDatePart(date,Calendar.MONTH)+1);
        turnoverStatistics.setDay(DateUtil.getDatePart(date,Calendar.DAY_OF_MONTH));
//        turnoverStatistics.setFee(null);
//        List<Object[]> list6 = contractOrderMapper.getContractTurnoverBase();
//        for(Object[] objects:list6){
//            turnoverStatistics.setUnit(objects[0].toString());
//            turnoverStatistics.setDate(DateUtil.strToDate((String)objects[1],DateUtil.YYYY_MM_DD));
//            turnoverStatistics.setAmount((BigDecimal) objects[3]);
//            turnoverStatistics.setType(TransactionTypeEnum.CONTRACT_BASE);
//            mongoTemplate.insert(turnoverStatistics,"turnover_statistics");
//        }
//
//        /**
//         * 合约成交量
//         */
//        List<Object[]> list7 = contractOrderMapper.getContractTurnoverCoin();
//        for(Object[] objects:list7){
//            turnoverStatistics.setUnit(objects[0].toString());
//            turnoverStatistics.setAmount((BigDecimal) objects[3]);
//            turnoverStatistics.setType(TransactionTypeEnum.CONTRACT_COIN);
//            turnoverStatistics.setDate(DateUtil.strToDate((String)objects[1],DateUtil.YYYY_MM_DD));
//            mongoTemplate.insert(turnoverStatistics,"turnover_statistics");
//        }
//        /**
//         * 合约交易手续费
//         */
//        ProjectionOperation projectionOperation1 =  Aggregation.project("time","type","unit","fee");
//
//        Criteria operator1 = Criteria.where("coinName").ne("").andOperator(
//                Criteria.where("type").is("CONTRACT")
//        );
//        MatchOperation matchOperation1 = Aggregation.match(operator1);
//        GroupOperation groupOperation1 = Aggregation.group("unit","type").sum("fee").as("feeSum") ;
//
//        Aggregation aggregation1 = Aggregation.newAggregation(projectionOperation1, matchOperation1, groupOperation1);
//        // 执行操作
//        AggregationResults<Map> aggregationResults1 = this.mongoTemplate.aggregate(aggregation1, "order_detail_aggregation", Map.class);
//        List<Map> list8 = aggregationResults1.getMappedResults();
//        for(Map map:list8){
//            turnoverStatistics.setFee(new BigDecimal(map.get("feeSum").toString()));
//            turnoverStatistics.setAmount(null);
//            turnoverStatistics.setDate(new Date(Long.valueOf(map.get("time").toString())*1000));
//            turnoverStatistics.setUnit(map.get("unit").toString());
//            turnoverStatistics.setType(TransactionTypeEnum.CONTRACT);
//            mongoTemplate.insert(turnoverStatistics,"turnover_statistics");
//        }
        /**
         * 合约成交额
         */
        turnoverStatistics.setFee(null);
        List<Object[]> list6 = contractOrderMapper.getContractTurnoverBase(dateStr);
        for(Object[] objects:list6){
            turnoverStatistics.setUnit(objects[0].toString());
            turnoverStatistics.setAmount((BigDecimal) objects[3]);
            turnoverStatistics.setType(TransactionTypeEnum.CONTRACT_BASE);
            mongoTemplate.insert(turnoverStatistics,"turnover_statistics");
        }

        /**
         * 合约成交量
         */
        List<Object[]> list7 = contractOrderMapper.getContractTurnoverCoin(dateStr);
        for(Object[] objects:list7){
            turnoverStatistics.setUnit(objects[0].toString());
            turnoverStatistics.setAmount((BigDecimal) objects[3]);
            turnoverStatistics.setType(TransactionTypeEnum.CONTRACT_COIN);
            mongoTemplate.insert(turnoverStatistics,"turnover_statistics");
        }
        /**
         * 合约交易手续费
         */
        ProjectionOperation projectionOperation1 = Aggregation.project("time","type","unit","fee");

        Criteria operator1 = Criteria.where("coinName").ne("").andOperator(
                Criteria.where("time").gte(DateUtil.YYYY_MM_DD_MM_HH_SS.parse(dateStr+" 00:00:00").getTime()/1000),
                Criteria.where("time").lte(DateUtil.YYYY_MM_DD_MM_HH_SS.parse(dateStr+" 23:59:59").getTime()/1000),
                Criteria.where("type").is("CONTRACT")

        );

        MatchOperation matchOperation1 = Aggregation.match(operator1);

        GroupOperation groupOperation1 = Aggregation.group("unit","type").sum("fee").as("feeSum") ;

        Aggregation aggregation1 = Aggregation.newAggregation(projectionOperation1, matchOperation1, groupOperation1);
        // 执行操作
        AggregationResults<Map> aggregationResults1 = this.mongoTemplate.aggregate(aggregation1, "order_detail_aggregation", Map.class);
        List<Map> list8 = aggregationResults1.getMappedResults();
        for(Map map:list8){
            turnoverStatistics.setFee(new BigDecimal(map.get("feeSum").toString()));
            turnoverStatistics.setAmount(null);
            turnoverStatistics.setUnit(map.get("unit").toString());
            turnoverStatistics.setType(TransactionTypeEnum.CONTRACT);
            mongoTemplate.insert(turnoverStatistics,"turnover_statistics");
        }
    }
    private List<Date> getDateList() throws ParseException {
        List<Date> list = new ArrayList<>() ;

        Date date = memberDao.getStartRegistrationDate();
        String dateStr = DateUtil.YYYY_MM_DD.format(date) ;
        date = DateUtil.YYYY_MM_DD.parse(dateStr);

        Calendar calendar = Calendar.getInstance() ;
        calendar.setTime(date);
        Date endDate = DateUtil.dateAddDay(new Date(),-1) ;
        while(date.before(endDate)){
            list.add(date);
            calendar.add(Calendar.DAY_OF_MONTH,1);
            date = calendar.getTime() ;
        }
        return list;
    }
}
